#include <Arduino.h>
#include "mqtt.h"
#include <base64.h>
#include <Crypto.h>
#include "espcrypto.h"
#include <ArduinoJson.h>
#include <Preferences.h>
#include "espcrypto.h"
#include "config.h"
#include "mainfunc.h"
#include "blefunc.h"
#include "httpfunc.h"
#include "NTPTime.h"
#include "mainfunc.h"
#include "bucket_plant_water/bucket_plant_water.h"
#include "ESP32Time.h"
#include "ActionCtrl.h"
#include "global.h"
#include "BizUtils.h"
#include <WiFi.h>
#include "global.h"

#include "test.h"
#include "queue.h"
#include "ota.h"


extern int RED_LIGHT_PIN;
extern int GREEN_LIGHT_PIN;
extern int BLUE_LIGHT_PIN;
extern int BEEP_PIN;


static const int SUN_PIN = 5;
static const int TEMP_PIN = 1;
static const int WATER_PIN = 3;
static const int VCC_PIN = 4;
static const int VCC_SWITCH__PIN = 6;
static const int HUMI_PIN = 2;



Queue vccHumiQueue;

static void sendDataHumi();


static void delayFunc(String s)
{

  if (s.equals("5"))
  {
    Serial.println("delayFunc");
    startApp(true);
    removeGlobalTimerCallBack("delayStartApp");
  }
}



static void sendDataCallBack(String time)
{

  long t = time.toInt();
  long frequency = getGlobalLocalConfig()->getTypeConfig()->getFrequencyDaytime();
  // frequency =15;
  if (t % frequency == 0)
  {
    setSendData(true);
  }
}

static void connectWiFiCallback(String s)
{
  long t = s.toInt();
  if (t % 30 == 0)
  {
    beep(true);
    delay(100);
    beep(false);
    setNeedConnectWiFi(true);
  }
}
 


static void delayStart()
{

  int appmode = getAppMode();
  printStr("appmode", appmode);

  if (appmode == 1) // 高性能模式
  {
    int ret = setUpWiFi();
    setWiFiConnected(ret == 0); // 连接wifi 并设置状态
    if (!isWiFiConnected())     // 联网失败
    {
      light("r", true); // 常亮红灯，未联网
      printStr("联网失败");
      addGlobalTimerCallBack("connectWiFi", connectWiFiCallback); // 30s重连一次
      beepTimes(2);
    }
    else
    { // 联网成功
      removeGlobalTimerCallBack("connectWiFi");
      addGlobalTimerCallBack("sendData", sendDataCallBack);
    
      // g 蓝色 b 红色 r 绿色
      blink("g", 60 * 60 * 24);
      printStr("联网成功");
      beepTimes(1);
     // sendDataBPW();
     sendDataHumi();
    }
  }

  if (appmode == 2) // 省电模式
  {

    light("b", true);
    addGlobalTimerCallBack("delayStartApp", delayFunc);

    // if (!isAllowOfflineRun())
    //   { // 如果不允许离线运行，并且是省电模式
    //     setTimerWakeup(String(600));
    //     setSleepMode(GPIO_TIMER_MODE);
    //     startSleep(0);
    //   }
  }
}

void intervalHumiAction(void *data)
{
  TimerActionB *a = static_cast<TimerActionB *>(data);
  // printStr("间隔模式 intervalTime", a->getIntervalTime());
  // printStr("间隔时长  ", a->getDuration());
  if (a == nullptr)
  {
    return;
  }
  if (a->action->id.equals("pump"))
  {
    pumpTime(a->getDuration());
  }
}

void singleHumiAction(void *data)
{
  TimerActionA *a = static_cast<TimerActionA *>(data);
  printStr("单次定时模式 actionTime", a->actionTime);
  if (a == nullptr)
  {
    return;
  }
  if (a->action->id.equals("pump"))
  {
    pumpTime(a->getDuration());
  }
}


 static int getHumiVccPinValue()
{
  digitalWrite(VCC_SWITCH__PIN, 0);
  delay(200);
  int vcc = analogRead(VCC_PIN);
  digitalWrite(VCC_SWITCH__PIN, 1);
  return vcc;
}

static float getHumiVcc()
{
 
    digitalWrite(VCC_SWITCH__PIN, 0);
    delay(200);
    int vcc = analogRead(VCC_PIN);
    digitalWrite(VCC_SWITCH__PIN, 1);
    vccHumiQueue.forceEnqueue(vcc);
  
  float avrVcc = vccHumiQueue.average();
  float total = (3055 - 2200) * 1.0;
  if (avrVcc <= 2200)
  {
    return 0.0;
  }
  float percent = (avrVcc - 2200) * 1.0 / total;
  float roundedNumber = round(percent * 100.0) / 100.0;
  return roundedNumber;
}
float getHumiSunPinValue(){


   //return analogRead(SUN_PIN);// GPIO5: ESP_ERR_INVALID_ARG
    //E (15094) ADC: ADC2 is no longer supported, please use ADC1. Search for errata on espressif website for more details. You can enable ADC_ONESHOT_FORCE_USE_ADC2_ON_C3 to force use ADC2

   return 0.0f;
}
float getHumiSun(){
   return getHumiSunPinValue()/3000*1.0f;
}





static float getHumiPinValue(){
   return analogRead(HUMI_PIN);
}

static float getHumi(){
   return getHumiPinValue()*1.0f/3000*1.0f;
}
// 所有的http请求回调都在这
static void onBackHumi(String data)
{

  Serial.println(data);
  Serial.println("返回的data 长度：");
  Serial.println(data.length());

 
  if (isDev())
  {
    beep(true);
    delay(5);
    beep(false);
  }
  // 静态JsonDocument，用于解析JSON
  JsonDocument doc;
  DeserializationError error = deserializeJson(doc, data);
  if (error)
  {
    Serial.print(F("deserializeJson() failed: "));
    Serial.println(error.f_str());
    return;
  }

  String msg = doc["msg"];
  if (msg.equals("device_config"))
  {
    if (doc["data"] == nullptr)
    {
      Serial.println("返回的data==null");
      return;
    }
    String timerAction = doc["data"]["timerAction"];
    String localConfig = doc["data"]["localConfig"];
    //Serial.println(timerAction);
    //Serial.println(localConfig);


    if (!isStringEmpty(timerAction))
    {
      if (parseTimerActionString(timerAction))
      {
        putPreferenceString("timerAction", timerAction);
        Serial.println("timerAction 保存Success");
      }
    }
    if (localConfig != NULL && !localConfig.isEmpty())
    {
      Serial.println("解析localConfig 开始 ");
      String runMode = doc["data"]["localConfig"]["typeConfig"]["runMode"];
      printStr("runMode--->",runMode);
      if(!isStringEmpty(runMode)){
        //如果运行模式改变了，就需要reboot
        if(getGlobalLocalConfig()->getTypeConfig()->getRunMode()!=runMode.toInt()){
          printStr("runMode  已改变，请求重启系统");
          setReboot(true);
        }
      }
      if (parseLocalConfigString(localConfig))
      {
        putPreferenceString("localConfig", localConfig);
        Serial.println("localConfig 保存Success");
      }
      Serial.println("解析localConfig 结束 ");
    }

  if(isReboot()){
    printStr("模式改变重启系统");
    delay(2000);
    ESP.restart();
  }

    return;
  }
}

static void sendDataHumi(float temp, 
float vcc, int vcc_pin,
 float humi, int humi_pin,
 float sun,int sun_pin)
{
  JsonDocument doc;
  doc["deviceId"] = getEspId();

  StaticJsonDocument<200> doc1;            // 分配200字节的静态内存给JSON文档
  JsonObject data = doc1.to<JsonObject>(); // 获取JsonObject

  data["temp"] = temp;
  data["vcc"] = vcc;
  data["vcc_pin"] = vcc_pin;
  data["humi"] = humi;
  data["humi_pin"] = humi_pin;
  data["sun"] = sun;
  data["sun_pin"] = sun_pin;

  data["rssi"] = getRssi();
  data["ip"] = WiFi.localIP();
  String jsonString;
  serializeJson(data, jsonString);

  doc["data"] = jsonString;

  String jsonString1;
  serializeJson(doc, jsonString1);

  Serial.println(jsonString1);

  requestPost(WEB_SERVER_URL + "/data/addSensorData", String(jsonString1), onBackHumi);

  // publish("sensor_data",jsonString1.c_str());
}



static void sendDataHumi()
{
  float temp = getTemp();
  float vcc = getHumiVcc();
 
  printStr("temp", temp);
  printStr("vcc", vcc);
 
 
  sendDataHumi(temp,
   vcc,
   getHumiVccPinValue(),
   getHumi(),
   getHumiPinValue(),
    getHumiSun() ,
    getHumiSunPinValue());
  if(isReboot()){
    printStr("模式改变重启系统");
    delay(2000);
    ESP.restart();
  }
}

static void initPortHumi(){
 
  pinMode(RED_LIGHT_PIN, OUTPUT);
  pinMode(GREEN_LIGHT_PIN, OUTPUT);
  pinMode(BLUE_LIGHT_PIN, OUTPUT);

 
  pinMode(BEEP_PIN, OUTPUT);
 // pinMode(VCC_SWITCH__PIN, OUTPUT);

  pinMode(VCC_PIN, INPUT_PULLDOWN);

  //pinMode(SUN_PIN, INPUT_PULLDOWN);
  pinMode(TEMP_PIN, INPUT_PULLDOWN);
  //pinMode(HUMI_PIN, OUTPUT);//应该是input

  pinMode(HUMI_PIN, INPUT_PULLDOWN);
 // analogSetPinAttenuation(HUMI_PIN, ADC_ATTENDB_MAX);

}



void setupMainHumi()
{
  Serial.begin(9600);

  setDeviceType("humi_sensor_v1");
  //clearPreference();
  Serial.println("start .....");
  printStr("App Type",getDeviceType());
 
 
  initPortHumi();
  pump(false);
  beep(false);
  attachButtonClick();
  config();
  setupWatchDog();
  closeRGB();
  printStr("env:", getEnv());
    if (!isActive())
  {
     printStr("未激活");
    blink("r", 60 * 10);
    setSleepMode(GPIO_MODE);
    startSleep(60 * 100); // 十分钟后未连接就休眠
    setupBle();
    startAdvertising();
    return;
  }
  if (isHasUpgrade())
  {
    printStr("有新版本升级");
    setUpWiFi();
    
    updateOTA();
    return;
  }
  attachGlobalTimer();

  parseFromPreference(); // 没有激活不要触发定时任务
  setupCrypto();
  light("b", true);
  delay(3000);
  Serial.println("start app");
  getGlobalLocalConfig()->print();
  setupMain();
  delayStart();
  addGlobalFuncCallBack("singleAction", singleHumiAction);
  addGlobalFuncCallBack("intervalAction", intervalHumiAction);

 
}

void loopMainHumi()
{

  loopArduinoOTA();
  loopBtn();
  loopMain();
  if(!isActive()){
    return ;
  }
 // printStr("isActive");
  excuteTimerAction();
  if (getAppMode() == 1)
  {
    if (isSendData())
    {
      printStr("sendData");
     // sendDataBPW();
     sendDataHumi();
     setSendData(false);
       printStr("数据发送完毕");
      if (isHasUpgrade())
      {
        printStr("有新版本升级");
        setUpWiFi();
        updateOTA();
        return;
      }
    }

    return;
  }

  if (getAppMode() == 2 && isAppStart())
  {
    light("g", true);
    setUpWiFi();
    //sendDataBPW();
    sendDataHumi();
  

    setSleepMode(GPIO_TIMER_MODE);
    startSleep(0); // 唤醒的间隔时间从typeconfig中设置
  }
}
